function hr_res101(mode)

if nargin < 1 || isempty(mode)
  mode = 'train';
end

%% general settings 
overWrite = false;
modelType = 'resnet-101-simple';
pretrainModelPath = 'models/imagenet-resnet-101-dag.mat';
inputSize = [500, 500];
trainFn = '@cnn_train_dag_hardmine';
batchGetterFn = '@cnn_get_batch_hardmine';
maxClusterSize = [inf, inf];
minClusterSize = [10, 10];
nmsThresh = 0.3;
numSubBatches = 1;
batchSize = 12;
numEpochs = 50;
tag = '';
gpus = [1];
if numel(gpus) > 1
  batchSize = batchSize * numel(gpus);
end

testTag = '';
testSet = 'val';
testMultires = true;

clusterNum = 25;
clusterName = 'scaled';
skipLRMult = [0 1 0.1];     % separate learning rate for skip connections from res5, res4, res3
learningRates = [1e-4*ones(1,30)];

allscale_templateIds = [5:12];   % Type-A 
onescale_templateIds = [19:25];  % Type-B 

switch mode
  case 'train'
    % we still need an input size so that we know what to crop 
    cnn_widerface('inputSize', inputSize, ...
                  'minClusterSize', minClusterSize, ...
                  'maxClusterSize', maxClusterSize, ...
                  'pretrainModelPath', pretrainModelPath, ...
                  'clusterNum', clusterNum, ...
                  'clusterName', clusterName, ...
                  'modelType', modelType, ...
                  'trainFn', trainFn, ...
                  'batchGetterFn', batchGetterFn, ...
                  'batchSize', batchSize, ...
                  'numEpochs', numEpochs, ...
                  'numSubBatches', numSubBatches,...
                  'gpus', gpus, ...
                  'skipLRMult', skipLRMult, ...
                  'learningRate', learningRates, ...
                  'tag', tag);
  case 'vis'
    for i = 20
      cnn_widerface_test_AB('overWrite', overWrite, ...
                            'inputSize', inputSize, ...
                            'clusterNum', clusterNum, ...
                            'clusterName', clusterName, ...
                            'testMultires', testMultires, ...
                            'noUpsampling', false, ...
                            'noOrgres', false, ...
                            'noDownsampling', false, ...
                            'allscale_templateIds', allscale_templateIds, ...
                            'onescale_templateIds', onescale_templateIds, ...
                            'tag', tag, ... 
                            'testTag', testTag, ...
                            'inputSize', inputSize, ...
                            'batchSize', batchSize, ...
                            'numSubBatches', numSubBatches,...
                            'modelType', modelType, ...
                            'pretrainModelPath', pretrainModelPath, ...
                            'vis', vis, 'gpus', gpus, ...
                            'probThresh', probThresh, ...
                            'nmsThresh', nmsThresh, ...
                            'testSet', testSet, ...
                            'testEpoch', i);
    end    
  case 'test'
    numEpochsToTest = numEpochs;
    gpus = [1 2 3 4];
    gpuNum = numel(gpus);
    taskPerGpu = 3;
    vis = false;
    probThresh = 0.03; 
    spmd (taskPerGpu * gpuNum)
      startEpoch = numEpochsToTest - labindex + 1;
      testEpochs = startEpoch : ((-1)*taskPerGpu*gpuNum) : 1;
      gpuId = gpus(ceil(labindex/taskPerGpu));
      for i = testEpochs
        cnn_widerface_test_AB('overWrite', overWrite, ...
                              'allscale_templateIds', allscale_templateIds, ...
                              'onescale_templateIds', onescale_templateIds, ...
                              'inputSize', inputSize, ...
                              'modelType', modelType, ...
                              'clusterNum', clusterNum, ...
                              'clusterName', clusterName, ...
                              'testMultires', testMultires, ...
                              'noUpsampling', false, ...
                              'noOrgres', false, ...
                              'noDownsampling', false, ...
                              'tag', tag, ... 
                              'testTag', testTag, ...
                              'vis', vis, ...
                              'gpus', gpuId, ...
                              'probThresh', probThresh, ...
                              'nmsThresh', nmsThresh, ...
                              'testSet', testSet, ...
                              'testEpoch', i);
      end
    end
  case 'eval'
    probThresh = 0.03; 
    for i = numEpochs:-1:1
      cnn_widerface_eval('clusterNum', clusterNum, ...
                         'clusterName', clusterName, ...
                         'testMultires', true, ...
                         'noUpsampling', false, ...
                         'noOrgres', false, ...
                         'noDownsampling', false, ...
                         'tag', tag, ...
                         'testTag', testTag, ...
                         'inputSize', inputSize, ...
                         'modelType', modelType, ...
                         'gpus', gpus, ...
                         'probThresh', probThresh, ...
                         'nmsThresh', nmsThresh, ...
                         'testSet', testSet, ...
                         'testEpoch', i);
    end
end
